﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using DocumentBuilder.Utils.Fomatter;

namespace DocumentBuilder.Components
{
    public class Field
    {
        private static readonly Regex FormatRegex = new Regex(@"\s*(?<formatter>[^/]+)\s*,\s*(?<format>[^/]+)", RegexOptions.Compiled);

        public String DbKey { get; set; }
        public String Name { get; set; }
        public String Format { get; set; }
        public String Value { get; set; }

        public String FormattedValue
        {
            get
            {
                if (Formatter == null)
                    return Value;
                else
                    return Formatter.Format(Value, Format);
            }
        }

        public IFormatter Formatter { get; private set; }

        public Field(String name, String dbKey, String format)
        {
            Name = name;
            DbKey = dbKey;
            Format = format;

            if (!String.IsNullOrEmpty(Format))
            {
                if (FormatRegex.IsMatch(Format))
                {
                    String[] result = FormatRegex.Match(Format).Result(String.Format("{0},{1}", "formatter", "format")).Split(',');
                    Formatter = FormatterFactory.CreateWith(result[0]);
                }
            }
        }

        public override string ToString()
        {
            return String.Format("Name: {0}, DbKey: {1}, Value: {2}", Name, DbKey, Value == null ? "" : Value.Substring(0, Math.Min(5, Value.Length)));
        }
    }

    public class ViewObject
    {
        public String Name { get; set; }
        public Dictionary<String, Field> Fields { get; set; }

        internal ViewObject(String name)
        {
            Name = name;
            Fields = new Dictionary<string, Field>();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public Field this[string index]
        {
            get { return Fields[index]; }
        }

        public static ViewObject Create(Document context, XmlNode viewObjectNode)
        {
            String name = String.Empty;
            if (viewObjectNode.Attributes != null
                    && viewObjectNode.Attributes["name"] != null)
                name = viewObjectNode.Attributes["name"].Value;

            var viewObject = new ViewObject(name);

            var fieldNodes = viewObjectNode.SelectNodes("./mapping/field");
            if (fieldNodes != null)
            {
                foreach (XmlNode fieldNode in fieldNodes)
                {
                    if (fieldNode.Attributes != null)
                    {
                        String fieldName = fieldNode.Attributes["name"] == null ? String.Empty : fieldNode.Attributes["name"].Value;
                        String dbKey = fieldNode.Attributes["dbKey"] == null ? String.Empty : fieldNode.Attributes["dbKey"].Value;
                        String formatter = fieldNode.Attributes["formatter"] == null ? String.Empty : fieldNode.Attributes["formatter"].Value;

                        viewObject.Fields.Add(fieldName, new Field(fieldName, dbKey, formatter));
                    }
                }
            }

            return viewObject;
        }

        public override string ToString()
        {
            var viewObjectBuilder = new StringBuilder("");
            foreach (var key in this.Fields.Keys)
            {
                viewObjectBuilder.Append(this.Fields[key].ToString() + ", ");
            }

            return viewObjectBuilder.ToString();
        }
    }
}